package com.fzebu.fastboot.token;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.*;

/**
 * @author: Jack
 * @create: 2019/12/6 19:21
 * @version: 1.0.0
 **/
public class JwtHelper {

    private static final String ISSUER = "WEAVER_TOKEN";

    private static final Long EXPIRES = 1800L;

    private JwtHelper() { }

    public static Util build(Long expires) {
        String secret = UUID.randomUUID().toString();
        return new Util(secret, ISSUER, expires);
    }

    public static Util build(String secret, String issuer, Long expires) {
        return new Util(secret, issuer, expires);
    }

    public static Util build(String secret, String issuer) {
        return new Util(secret, issuer, EXPIRES);
    }

    public static Util build(String secret) {
        return new Util(secret, ISSUER, EXPIRES);
    }

    public static Util build() {
        String secret = UUID.randomUUID().toString();
        return new Util(secret, ISSUER, EXPIRES);
    }

    public static class Util {

        private String secret;

        private String issuer;

        private Long expires;

        public Util(String secret, String issuer, Long expires) {
            this.secret = secret;
            this.issuer = issuer;
            this.expires = expires;
        }

        public String getToken(Map<String, String> claims) {
            return getToken(claims, this.expires);
        }

        public String getToken(Map<String, String> claims, Long expires) {
            // 生成过期时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.SECOND, expires.intValue());
            Date expiration = calendar.getTime();
            // 使用HMAC256进行加密
            Algorithm algorithm = Algorithm.HMAC256(this.secret);
            // 创建jwt
            JWTCreator.Builder builder = JWT.create()
                    .withIssuer(this.issuer)     // 发行人
                    .withExpiresAt(expiration);  // 过期时间点
            // 传入参数
            claims.forEach(builder::withClaim);
            return builder.sign(algorithm);
        }

        public Map<String, String> validate(String token) throws RuntimeException {
            // 使用HMAC256进行加密
            Algorithm algorithm = Algorithm.HMAC256(this.secret);
            // 解密
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(this.issuer)
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            Map<String, Claim> map = jwt.getClaims();
            Map<String, String> resultMap = new HashMap<>();
            map.forEach((k, v) -> resultMap.put(k, v.asString()));
            return resultMap;
        }
    }
}
